﻿using System;
using System.IO;
using System.Runtime.Serialization.Json;
using Petra.Gis.Geometry.Support;
using Petra.Gis.ReferenceSystemServices;
using Petra.Gis.ReferenceSystemServices.Transformations;

namespace testSRST
{
  public class testLCC4jtsk
  {


    public static void testMe()
    {

      recomputeOrigin();

      LambertConicConformalProjection lcc = (LambertConicConformalProjection)LambertConicConformalProjection.Create(createLCC(), true);

      //test JSON serialize...
      serializeToJson();

      //wgs bod v CR
      Coordinate sour = Coordinate.Parse("48°46′50.20133″N, 14°0′49.63044″E");

      //uprava meridianu na ferro a muzeme predstirat ze je to bod na besselove elipsoidu
      sour.lon -= -17.66666666666666666666666666666667;

      //31,6804529;48,7806114805556
      lcc.Transform(sour);

      lcc = (LambertConicConformalProjection)lcc.Inverse();

      lcc.Transform(sour);

      //vysledek transofrmace:792355,961967194;1182894,67236311

      //bod z WGS:1182833.62 792277.45

      string fStr = sour.ToString("deg->ddd:mm:ss|ne");


    }




    public static void serializeToJson()
    {
      MemoryStream m1 = new MemoryStream();

      DataContractJsonSerializer j1 = new DataContractJsonSerializer(typeof(ProjectedCoordinateSystem));

      j1.WriteObject(m1, createLCC());

      //1. test fromstream
      m1.Position = 0;

      //2.test from string
      String tstr = System.Text.Encoding.Default.GetString(m1.ToArray());

      DataContractJsonSerializer btOut = (DataContractJsonSerializer)j1.ReadObject(m1);

    }




    public static ProjectedCoordinateSystem createLCC()
    {


      //jtsk projected coordinate system...
      // WGS bounds 12.0900, 47.7400, 22.5600, 51.0500
      ProjectedCoordinateSystem cs = new ProjectedCoordinateSystem()
      {
        Axes = new AxisList
        {
          // note for axis directions
          new Axis(){ Name = "X", Orientation = Axis.South},
          new Axis(){ Name = "Y", Orientation = Axis.West}
        },
        Metadata = new Metadata()
        {
          Name = "s-jtsk",
          Authority = "EPSG",
          AuthorityCode = 2065,
          Abbreviation = "jtsk",
          Alias = "s-jtsk",
          Remarks = "Cesky narodni civilni referencni system pro katastr (Czech national civil projected coordinate system)"
        },
        DefaultEnvelope = new BoundingBox()
        {
          //Y = 431680, X = 935198; Y = 904554, X=1227672
          Left = 431680,
          Bottom = 935198,
          Right = 904554,
          Top = 1227672
        },
        VerticalDatum = new VerticalDatum()
        {
          Type = VerticalDatum.SeaLevel,
          VerticalUnit = DistanceUnit.Meter,
          Metadata = new Metadata()
          {
            Name = "balt po vyrovnani",
            Abbreviation = "bpv",
            Authority = "CUZK",
            AuthorityCode = -1,
            Alias = "bpv",
            Remarks = "balt po vyrovnani nahrazuje starsi Trieste (baltic after correction, replaces old Austrian-Hungarian monarchy Trieste)"
          }
        },
        Unit = DistanceUnit.Meter,
        ProjectionDef = new ProjectionDefinition()
        {
          ClassName = "lambert conic conformal",
          Metadata = new Metadata()
          {
            Name = "Lambert conic conformal projection 2SP with oblique",
            Authority = "EPSG",
            AuthorityCode = 9802,
            Abbreviation = "LCC",
            Remarks = "for oblique this projection turns into conformal cone - gauss sphere - ellipsoid"
          },
          AngularParameterUnit = AngularUnit.Degrees,
          DistanceParameterUnit = DistanceUnit.Meter,
          Parameters = new TransformParameters()
          {
            {"latitude_of_origin", 90.0},   //origin Y on gauss sphere
            {"central_meridian", 0.0},      //origin X on gauss sphere
            {"standard_parallel_1", 78.5},  //cone 1sp on gauss sphere
            {"false_easting", 0.0},         //unused
            {"false_northing", 0.0},        //unused
            {"scale_factor", 0.9999},       //scale factor

            //oblique extended parameters of lcc
            //ellipsoidal latitude for standard parallel
            //for jtsk 49.5 on ellipsoid = 49.4599572917 on gauss sphere
            {"oblique_standard_parallel", 49.5},
            {"oblique_pole_latitude", 59.7118602500},   //on gauss sphere
            {"oblique_pole_longitude", 42.5253936806}, //on gauss sphere
            //{"oblique_pole_latitude", 59,6762038153976}, //on bessel@rounded ferro
            //{"oblique_pole_longitude", 42,5}, //on bessel@rounded ferro
          }
        },
        // krovak geographic base datum...
        GeographicCoordinateSystem = new GeographicCoordinateSystem()
        {
          Datum = HorizontalDatum.Krovak,
          Axes = new AxisList
          {
            new Axis(){ Name = "E", Orientation = Axis.East},
            new Axis(){ Name = "N", Orientation = Axis.North},
          },
          PrimeMeridian = PrimeMeridian.RoundedFerro, //special meridian for krovak
          Metadata = new Metadata()
          {
            Name = "Krovak geographic space",
            Authority = "CUZK",
            AuthorityCode = -1,
          },
          Unit = AngularUnit.Degrees
        }

      };

      return cs;
    }






    public static void recomputeOrigin()
    {
      ProjectedCoordinateSystem p = createLCC();

      SphericConformalTransform s = new SphericConformalTransform(p.GeographicCoordinateSystem, 49.5, AngularUnit.Degrees, false);

      Coordinate c = new Coordinate(59.7118602500, 42.5253936806); //lat,lon

      s.Transform(c);



    }
  
  
  
  }

}
